<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2020/12/20
 * Time: 15:10
 * @link http://www.lmterp.cn
 */

namespace app\admin\controller\pur;

use app\admin\controller\BaseController;
use app\common\library\Tools;
use app\common\model\ChannelExpress;
use app\common\model\FinanceBank;
use app\common\model\FinanceCash;
use app\common\model\JobFlowModule;
use app\common\model\Producer;
use app\common\model\Purchase;
use app\common\model\PurchaseExchange;
use app\common\model\PurchaseTrack;
use app\common\service\product\StockService;
use app\common\service\purchase\RExService;

/**
 * 采购换货单
 * Class ExchangeController
 * @package app\admin\controller\pur
 */
class ExchangeController extends BaseController
{
    protected $moduleName = 'purchase_exchange';

    /**
     * 换货单列表
     * @date 2021/01/23
     * @author longli
     */
    public function index()
    {
        if($this->request->isAjax())
        {
            $exchange = PurchaseExchange::with(["purchase"])
                ->order("status, exchange_id desc");
            $this->search($exchange);
            $limit = $this->getPageSize();
            $exchange = $exchange->paginate($limit);
            $this->assign("status_cancel", PurchaseExchange::STATUS_EXCHANGE_CANCEL);
            $this->assign("status_out", PurchaseExchange::STATUS_EXCHANGE_OUT);
            $this->assign("is_show_check", $this->user->hasPermissions('/pur/exchange/check'));
            $this->assign("list", $exchange->getCollection());
            $this->assign("page", $exchange->render());
            return $this->fetch('lists');
        }
        $this->assign("check_status", JobFlowModule::$CHECK_STATUS);
        $this->assign("producer", Producer::getAll());
        $this->assign("buyers", Purchase::getBuyers());
        $this->assign("status", PurchaseExchange::$STATUS_EXCHANGE);
        return $this->fetch('index');
    }

    /**
     * 搜索换货单
     * @param $exchange
     * @date 2021/01/23
     * @author longli
     */
    private function search($exchange)
    {
        $this->searchModel($exchange, [
            'eq' => ['producer_id', 'status', 'track_num', 'check_status'],
            'times' => ['create_time'],
        ]);
        // 处理子查询
        $subSel = ['buyer_user_id'];
        $pWhere = [];
        foreach($subSel as $f)
        {
            $text = $this->request->post($f, '', 'trim');
            if(empty($text) && !is_numeric($text)) continue;
            $pWhere[$f] = $text;
        }
        if($sn = $this->request->post('sn', '', 'trim'))
        {
            if($pTemp = Purchase::whereRaw("purchase_sn=? OR producer_sn=?", [$sn, $sn])->find())
            {
                $pWhere["purchase_id"] = $pTemp->purchase_id;
            }
            else
            {
                $exchange->where('exchange_sn', $sn);
            }
        }
        if(!empty($pWhere))
        {
            $exchange->where("purchase_id", "IN", function($query)use($pWhere)
            {
                $query->table(Purchase::getTable())->where($pWhere)->field("purchase_id");
            });
        }
    }

    /**
     * 换货单详情
     * @date 2021/01/23
     * @author longli
     */
    public function info()
    {
        $eid = $this->request->get("exchange_id");
        if(empty($eid)) $this->error("非法请求");
        $exchange = PurchaseExchange::get($eid);
        if(empty($exchange)) $this->error("换货单不存在");
        $this->assign("exchange_info", $this->renderInfo($exchange));
        $this->assign("exchange", $exchange);
        if($exchange->getData('check_status') != \app\common\model\JobFlowModule::CHECK_NO_NEED)
        {
            $this->assignCheck($eid);
        }
        return $this->fetch('info');
    }

    /**
     * 渲染自定义换货单详情模板
     * @param PurchaseExchange $exchange 换货单数据模型
     * @return string|void
     * @date 2021/01/11
     * @author longli
     */
    private function renderInfo($exchange)
    {
        return $this->renderTerp(PurchaseExchange::class, $exchange->exchange_id, "pur/purchase/info/purchase_exchange");
    }

    /**
     * 创建换货单
     * @date 2020/12/02
     * @author longli
     */
    public function add()
    {
        if($this->request->isPost())
        {
            $this->validateAdd();
            $data = [
                'purchase_id' => $this->request->post('purchase_id'),
                'express_id' => $this->request->post('express_id'),
                'account' => FinanceBank::get($this->request->post('bank_id'))->account,
                'pay_type' => $this->request->post('pay_type'), // 运费方式
                'cash_type' => FinanceCash::CASH_TYPE_BANK,
                'cash_date' => $this->request->post('cash_date'),
                'logistics_price' => $this->request->post('logistics_price', 0),
                'track_num' => $this->request->post('track_num'),
                'remark' => $this->request->post('remark'),
                'is_check' => $this->request->post('is_check', 0),
            ];
            !empty($data['express_id']) && ($data['logistics_name'] = ChannelExpress::getNameById($data['express_id']));
            $info = [];
            $post = $this->request->post();
            foreach($post['sku'] as $k => $v)
            {
                $info[] = [
                    "sku" => $v,
                    "qty" => $post['qty'][$k],
                    "cost_desc" => isset($post['cost_desc'][$k]) ? $post['cost_desc'][$k] : '',
                    "remark" => isset($post['info_remark'][$k]) ? $post['info_remark'][$k] : '',
                ];
            }
            $msg = RExService::getInstance()->addExchange($data, $info);
            if(!is_object($msg)) $this->error($msg);
            $this->success("添加换货单成功");
        }
        // 展示退货页面
        $purId = $this->request->get("purchase_id");
        if(empty($purId)) $this->error("非法请求");
        if(!($purchase = Purchase::get($purId))) $this->error("采购单不存在");
        if(!in_array($purchase->getData('order_status'), [
            Purchase::ORDER_STATUS_RECV, Purchase::ORDER_STATUS_EXCEPTION,
            Purchase::ORDER_STATUS_CHE_INFO, Purchase::ORDER_STATUS_IN,
            Purchase::ORDER_STATUS_IN_EX, Purchase::ORDER_STATUS_WAIT_UP,
            Purchase::ORDER_STATUS_IN_PART, Purchase::ORDER_STATUS_IN_SUCC,
            Purchase::ORDER_STATUS_CHE_EX
        ])) $this->error("当前采购单状态为【{$purchase->order_status}】不能换货");
        $this->assign('pay_type', PurchaseTrack::$PAY_TYPE);
        $this->assign("banks", FinanceBank::getAll());
        $this->assign('express', ChannelExpress::getAll());
        $this->assign("purchase", $purchase);
        return $this->fetch('add');
    }

    /**
     * 验证添加换货单数据
     * @return bool
     * @date 2021/02/01
     * @author longli
     */
    private function validateAdd()
    {
        $data = $this->request->post();
        $validate = \think\facade\Validate::make([
            'purchase_id'  => 'require',
            'logistics_price'  => 'egt:0',
            'sku'  => 'array|require',
            'qty'  => 'array|require',
        ],[
            'purchase_id.require' => '采购ID必填',
            'logistics_price.egt' => '物流费用不能小于0',
            'sku.require' => 'SKU必填',
            'sku.array' => 'SKU必须是数组',
            'qty.require' => '数量必填',
            'qty.array' => '数量必须是数组',
        ]);
        if(!$validate->batch()->check($data))
            $this->error(join(", ", $validate->getError()));
        $error = [];
        foreach($data['qty'] as $k => $v)
        {
            if($v < 1) $error[] = "SKU【{$data['sku'][$k]}】数量不能小于1";
        }
        if(!empty($error)) $this->error(join(", ", $error));
        return true;
    }

    /**
     * 取消换货单
     * @date 2021/01/23
     * @author longli
     */
    public function cancel()
    {
        $ids = $this->request->get("ids");
        if(empty($ids)) $this->error("非清请求");
        $fail = [];
        foreach(PurchaseExchange::whereIn("exchange_id", $ids)->select() as $exchange)
        {
            if($exchange->getData('status') > PurchaseExchange::STATUS_EXCHANGE_WAIT_OUT)
            {
                $fail[] = $exchange->exchange_id;
                continue;
            }
            $exchange->status = PurchaseExchange::STATUS_EXCHANGE_CANCEL;
            $exchange->save();
        }
        Tools::equalsArray($fail, explode(',', $ids))
            ? $this->error("取消失败")
            : $this->success("取消成功");
    }

    /**
     * 占用库存
     * @date 2021/07/02
     * @author longli
     */
    public function lock()
    {
        // @todo
        StockService::purchaseExchangeUnlock();
    }
}